#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "od_udp_recv.h"
#include "od_rtp_unpack.h"
#include "decoder_param.h"
#include "HisiDecVpssOut.h"
#include "HisiDecSendStream.h"
#include "usecase_decoder.h"

typedef struct connect_str_s
{
    char str[OD_MAX_PATH_LEN];
}connect_str_t;



static void * udp_recv_vid_static_create(void * usr, char * task_name)
{
    udp_recv_static_params_t * thr_static_params = NULL;

    thr_static_params = (udp_recv_static_params_t *)od_malloc(sizeof(udp_recv_static_params_t));
    if(NULL == thr_static_params)
    {
        RPT(RPT_ERR, "NULL pointer, error");
        return NULL;
    }
    *thr_static_params = glb_udp_recv_static_params_default;
    strncpy(thr_static_params->task_name, task_name, OD_MAX_OBJ_NAME - 1);
    thr_static_params->buf_nums = 10; 

    return (void *)thr_static_params;
}

static void * udp_recv_vid_dynamic_create(void * usr)
{
    udp_recv_dynamic_params_t * thr_dynamic_params = NULL;

    thr_dynamic_params = (udp_recv_dynamic_params_t *)od_malloc(sizeof(udp_recv_dynamic_params_t));
    if(NULL == thr_dynamic_params)
    {
        RPT(RPT_ERR, "NULL pointer, error");
        return NULL;
    }

    *thr_dynamic_params = glb_udp_recv_dynamic_params_default;
    thr_dynamic_params->recv_enable = OD_ON;
    thr_dynamic_params->recv_method = SOCK_UDP;
    thr_dynamic_params->recv_cast_mode = UDP_SOCKET_UNICAST;
    strncpy(thr_dynamic_params->recv_multi_addr, "224.1.1.1", UDP_ADDR_STR_LEN -1 );
    thr_dynamic_params->recv_port = 30000;
    strncpy(thr_dynamic_params->local_addr, "172.16.60.168", UDP_ADDR_STR_LEN -1 );

    return (void *)thr_dynamic_params;
}

static void * rtp_unpack_static_create(void *usr, char *task_name)
{
    od_rtp_unpack_static_params *static_params = NULL;

    static_params = (od_rtp_unpack_static_params *)od_malloc(sizeof(od_rtp_unpack_static_params));
    if(NULL == static_params)
    {
        RPTERR("malloc falied");
        return NULL;
    }

    *static_params = glb_od_rtp_unpack_static_params_default;

    static_params->vid_tube_bufnums = 10;
    static_params->vid_tube_bufsize = 1024*768;

    static_params->aud_tube_bufnums = 0;
    static_params->aud_tube_bufsize = 0;

    strncpy(static_params->task_name, task_name, OD_MAX_OBJ_NAME - 1);

    return static_params;
}

static void *hisi_vpss_ctl_static_create(void * usr, char * task_name)
{
    hisiDecVpssOut_static_params * thr_static_params = NULL;

    thr_static_params = (hisiDecVpssOut_static_params *)od_malloc(sizeof(hisiDecVpssOut_static_params));
    if(NULL == thr_static_params)
    {
        RPT(RPT_ERR, "NULL pointer, error");
        return NULL;
    }
    *thr_static_params = glb_hisiDecVpssOut_static_params_default;
    thr_static_params->task_name = task_name;

    return (void *)thr_static_params;
}

static void * hisi_vpss_ctl_dynamic_create(void * usr)
{
    hisiDecVpssOut_dynamic_params * thr_dynamic_params = NULL;

    thr_dynamic_params = (hisiDecVpssOut_dynamic_params *)od_malloc(sizeof(hisiDecVpssOut_dynamic_params));
    if(NULL == thr_dynamic_params)
    {
        RPT(RPT_ERR, "NULL pointer, error");
        return NULL;
    }

    *thr_dynamic_params = glb_hisiDecVpssOut_dynamic_params_default;

    return (void *)thr_dynamic_params;
}

static void *hisi_dec_static_create(void * usr, char * task_name)
{
    hisi_dec_static_params * thr_static_params = NULL;
    static int idx = 0;

    thr_static_params = (hisi_dec_static_params *)od_malloc(sizeof(hisi_dec_static_params));
    if(NULL == thr_static_params)
    {
        RPT(RPT_ERR, "NULL pointer, error");
        return NULL;
    }
    *thr_static_params = glb_hisi_dec_static_params_default;
    thr_static_params->task_name = task_name;
    thr_static_params->u32Chn = idx++;

    return (void *)thr_static_params;
}

static void * hisi_dec_dynamic_create(void * usr)
{
    hisi_dec_dynamic_params * thr_dynamic_params = NULL;

    thr_dynamic_params = (hisi_dec_dynamic_params *)od_malloc(sizeof(hisi_dec_dynamic_params));
    if(NULL == thr_dynamic_params)
    {
        RPT(RPT_ERR, "NULL pointer, error");
        return NULL;
    }

    *thr_dynamic_params = glb_hisi_dec_dynamic_params_default;

    return (void *)thr_dynamic_params;
}


static const app_task_spawn_info_t app_list[]=
{
    {TSK_UDP_RECV_VID_0, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_1, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_2, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_3, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_4, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_5, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_6, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_7, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },

    {TSK_UDP_RECV_VID_8, 87,
        (void *)udp_recv_vid_static_create, (void *)udp_recv_vid_dynamic_create, (void *)udp_recv_create,
    },



    {TSK_RTP_UNPACK_0, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_1, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_2, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_3, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_4, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_5, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_6, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_7, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },

    {TSK_RTP_UNPACK_8, 87,
        (void *)rtp_unpack_static_create, NULL, (void *)od_rtp_unpack_create,
    },



    {TSK_HISI_DEC_SEND_STREAM_0, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_1, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_2, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_3, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_4, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_5, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_6, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_7, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_SEND_STREAM_8, 87,
        (void *)hisi_dec_static_create, hisi_dec_dynamic_create, (void *)hisi_dec_create,
    },

    {TSK_HISI_DEC_VPSS_CTL, 87,
        (void *)hisi_vpss_ctl_static_create, hisi_vpss_ctl_dynamic_create, (void *)hisiDecVpssOut_create,
    },

    {"", 0,
        NULL, NULL, NULL,
    }

};

static task_name_t  decoder_starting_list[] =
{
    /* video */
    {TSK_HISI_DEC_VPSS_CTL},
    {TSK_HISI_DEC_SEND_STREAM_0},
    {TSK_RTP_UNPACK_0},
    {TSK_UDP_RECV_VID_0},

    {TSK_HISI_DEC_SEND_STREAM_1},
    {TSK_RTP_UNPACK_1},
    {TSK_UDP_RECV_VID_1},

    {TSK_HISI_DEC_SEND_STREAM_2},
    {TSK_RTP_UNPACK_2},
    {TSK_UDP_RECV_VID_2},

    {TSK_HISI_DEC_SEND_STREAM_3},
    {TSK_RTP_UNPACK_3},
    {TSK_UDP_RECV_VID_3},

    {TSK_HISI_DEC_SEND_STREAM_4},
    {TSK_RTP_UNPACK_4},
    {TSK_UDP_RECV_VID_4},

    {TSK_HISI_DEC_SEND_STREAM_5},
    {TSK_RTP_UNPACK_5},
    {TSK_UDP_RECV_VID_5},

    {TSK_HISI_DEC_SEND_STREAM_6},
    {TSK_RTP_UNPACK_6},
    {TSK_UDP_RECV_VID_6},

    {TSK_HISI_DEC_SEND_STREAM_7},
    {TSK_RTP_UNPACK_7},
    {TSK_UDP_RECV_VID_7},

    {TSK_HISI_DEC_SEND_STREAM_8},
    {TSK_RTP_UNPACK_8},
    {TSK_UDP_RECV_VID_8},
};

static connect_str_t  decoder_connect_list[] =
{
    /* video */
    {TSK_UDP_RECV_VID_0".out->"TSK_RTP_UNPACK_0".vid_in"},
    {TSK_RTP_UNPACK_0".vid_out->"TSK_HISI_DEC_SEND_STREAM_0"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_1".out->"TSK_RTP_UNPACK_1".vid_in"},
    {TSK_RTP_UNPACK_1".vid_out->"TSK_HISI_DEC_SEND_STREAM_1"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_2".out->"TSK_RTP_UNPACK_2".vid_in"},
    {TSK_RTP_UNPACK_2".vid_out->"TSK_HISI_DEC_SEND_STREAM_2"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_3".out->"TSK_RTP_UNPACK_3".vid_in"},
    {TSK_RTP_UNPACK_3".vid_out->"TSK_HISI_DEC_SEND_STREAM_3"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_4".out->"TSK_RTP_UNPACK_4".vid_in"},
    {TSK_RTP_UNPACK_4".vid_out->"TSK_HISI_DEC_SEND_STREAM_4"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_5".out->"TSK_RTP_UNPACK_5".vid_in"},
    {TSK_RTP_UNPACK_5".vid_out->"TSK_HISI_DEC_SEND_STREAM_5"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_6".out->"TSK_RTP_UNPACK_6".vid_in"},
    {TSK_RTP_UNPACK_6".vid_out->"TSK_HISI_DEC_SEND_STREAM_6"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_7".out->"TSK_RTP_UNPACK_7".vid_in"},
    {TSK_RTP_UNPACK_7".vid_out->"TSK_HISI_DEC_SEND_STREAM_7"."DEC_SEND_STREAM_IN_ES_NAME},

    {TSK_UDP_RECV_VID_8".out->"TSK_RTP_UNPACK_8".vid_in"},
    {TSK_RTP_UNPACK_8".vid_out->"TSK_HISI_DEC_SEND_STREAM_8"."DEC_SEND_STREAM_IN_ES_NAME},
};


int32_t decoder_start(od_framework_t * framework)
{
    int32_t ret = OD_OK;
    int i = 0;
    decoder_params_obj * params_obj = framework->param_table;

	/*根据启动任务名列表，创建实际任务*/
    ret = od_framework_load(framework, app_list, decoder_starting_list, sizeof(decoder_starting_list)/sizeof(task_name_t));

    /*连接任务间的tube*/
    for(i = 0; i < sizeof(decoder_connect_list)/sizeof(connect_str_t); i++)
    {
        ret = od_framework_connect(framework, decoder_connect_list[i].str);
        if(ret != OD_OK)
        {
            RPTERR("connect error; string is %s", decoder_connect_list[i].str);
            return OD_ERROR;
        }
    }
    
	/*从配置文件，加载所有参数*/
    jsparam_act_all(params_obj->decoder_json_hdl);
	
	/*启动所有线程任务*/
    ret = od_framework_start(framework, app_list, decoder_starting_list, sizeof(decoder_starting_list)/sizeof(task_name_t));

    return ret;
}

int32_t decoder_stop(od_framework_t * framework)
{
    int32_t ret = OD_OK;

    ret = od_framework_stop(framework, decoder_starting_list, sizeof(decoder_starting_list)/sizeof(task_name_t));
    RPT(RPT_WRN,"od_framework_stop end");

    return ret;
}

/*_*/

